package com.search.service;

import com.alibaba.fastjson2.JSONObject;
import com.search.entity.BorrowBook;
import com.search.entity.DoubanBook;
import com.search.examples.CapitalSearch;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
@Repository
public abstract class DoubanBookCapitalService {

    protected ThreadLocal<Integer> currentPageBookSum = ThreadLocal.withInitial(()->0);

    protected ThreadLocal<Boolean> isEmpty = ThreadLocal.withInitial(()->false);

    protected ThreadLocal<Integer> counter = ThreadLocal.withInitial(()->0);

    protected ThreadLocal<Integer> bookSum = ThreadLocal.withInitial(()->0);

    float ratingLine = 0.0f;

    int getDataType = 2;//0是库里没有，全线上查。1是库里走，不查线上。2是库里有部分数据，先从库里查，没有再查线上

    @Autowired
    protected BorrowBookService borrowBookService;

    @Autowired
    protected DoubanBookService doubanBookService;


    public abstract String getListIdfromUrl(String url);

    public abstract String dealUrl(String url,int bookSum);

    public abstract Integer bookSumIncrease(Integer bookSum);

    public abstract List<JSONObject> dealPageData(Document doc);

    Document getDoc(String url) throws InterruptedException {

        try{
            Connection connection = Jsoup.connect(url);
            return connection.get();
        }catch (Exception e){
            log.error("jsoup报错,重试"+url);
            Thread.sleep(3000);
            return getDoc(url);
        }
    }

    public DoubanBook getBookDetail(String detailUrl,String tag) throws Exception {

        Document detail = getDoc(detailUrl);
        int evaluateNum = 0;
        float rating = 0.0f;
        int beginIndex = detailUrl.substring(0,detailUrl.length()-1).lastIndexOf("/");
        String id = detailUrl.substring(beginIndex+1,detailUrl.length()-1);

        String name = detail.select("span[property='v:itemreviewed']").get(0).text().trim();
        Elements votes = detail.select("span[property='v:votes']");
        Elements averages = detail.select("strong[property='v:average']");
        log.info("线上查询图书详情"+detail.title());
        if(averages.size()>0){
            rating = Float.parseFloat(averages.get(0).text().trim());
        }

        if(votes.size()>0){
            evaluateNum = Integer.parseInt(votes.get(0).text().trim());
        }
        //Elements infos = detail.select("div#info");
        Element info = detail.getElementById("info");
        int isbnIndex=0;
        int subTitleIndex = 0;
        for(Node node:info.childNodes()){
            String text = node.toString();
            if(text.contains("ISBN")){
                //System.out.println(text);
                //System.out.println(node.siblingIndex());
                isbnIndex = node.siblingIndex();
            }
            if(text.contains("副标题")){
                subTitleIndex = node.siblingIndex();
                if(subTitleIndex>0){
                    String subTitle = info.childNodes().get(subTitleIndex+1).toString();
                    name += subTitle;
                }
            }

        }
        //System.out.println(info.childNodes().get(index+1).toString());
        String isbn = info.childNodes().get(isbnIndex+1).toString().trim();
        //存入豆瓣图书数据
        DoubanBook doubanBook = new DoubanBook();
        doubanBook.setBookName(name);
        doubanBook.setUrl(detailUrl);
        doubanBook.setRating(rating);
        doubanBook.setEvaluateNum(evaluateNum);
        doubanBook.setIsbn(isbn);
        doubanBook.setTag(tag);
        doubanBook.setInsertTime(new Date());
        /*if(detailUrl.contains("tag")){
            int tagIndex = detailUrl.indexOf("tag");
            int queIndex = detailUrl.indexOf("?");
            doubanBook.setTag(detailUrl.substring(tagIndex+4,queIndex-1));

        }*/
        doubanBook.setId(id);
        try{
            doubanBookService.saveNotNull(doubanBook);
        }catch (Exception e){
            log.error("豆瓣book插入出错"+name);
            throw e;
        }
        //log.info("豆瓣book插入"+isbn);
        return doubanBook;
    }

    public JSONObject queryBooks(String url, String source, String classify){

        int other = 0;
        int exist = 0;
        Document doc=null;
        JSONObject result = new JSONObject();
        String listId = getListIdfromUrl(url);
        //url = url+"/?start="+bookSum+"&type=S";
        List<JSONObject> urls = null;
        url = dealUrl(url,bookSum.get());
        do{
            try{
                int currentPageBookSum = 0;
                try{
                    url = url.replaceAll("\\d+",""+bookSum.get());
                    //connection.header("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" );
                   // connection.header("Accept-Encoding", "gzip, deflate, br, zstd");
                  //  connection.header("Accept-Language","zh-CN,zh;q=0.9");
                   // connection.header("Cookie","ll=\"108288\"; bid=9PA9e_qJqZs; _pk_id.100001.3ac3=ae6225e4795c08fb.1708685422.; __yadk_uid=NuUdMcdjODDfQo3cDrJfgYKIzQ3sF8R6; __utmv=30149280.6649; douban-fav-remind=1; _vwo_uuid_v2=D51DD5E04E1D38AE969571D3EC18FFBEE|bfae3d8c5137382994a284caf67d9bb2; _vwo_uuid_v2=D51DD5E04E1D38AE969571D3EC18FFBEE|bfae3d8c5137382994a284caf67d9bb2; __gads=ID=80b702e18622fd66:T=1712410692:RT=1715431296:S=ALNI_MZfVo7M1LcK0EchlcbOygX456BJEw; __gpi=UID=00000de2fd0fefee:T=1712410692:RT=1715431296:S=ALNI_MYMgWJtmI2J7oanVn4FmR3YRVMxKw; __eoi=ID=27e816b6c683fb5c:T=1712410692:RT=1715431296:S=AA-AfjZQZNN-p42pejVmWw_USe7f; FCNEC=%5B%5B%22AKsRol8MObwrmGfGtgEAUqItYLL02JvZxpba_VLMy6YLToyuFx6pBvSWrZkx7LK4F8Er7H6uN_5iH-k7j_FmNpLiUxcRbC60YKX9RNrP15eKck_uFMcVQn4Ru2l6C5ej-P6KlhzcGMVM8jER5_T56_oYq8rzfElB4A%3D%3D%22%5D%5D; push_doumail_num=0; push_noty_num=0; viewed=\"1813923_1459789_2046455_1552470_1727426_3614610_36577781_2176400\"; dbcl2=\"66490248:MZY+KE045E4\"; _ga_RXNMP372GL=GS1.1.1722351379.2.1.1722353631.28.0.0; _ga=GA1.1.413830873.1708960458; _ga_Y4GN1R87RG=GS1.1.1722426341.2.0.1722426341.0.0.0; ct=y; ck=723N; __utmc=30149280; __utmc=81379588; frodotk_db=\"d2abf14975f87a187803d3dc61e96e48\"; __utmz=30149280.1722599552.94.32.utmcsr=search.douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/movie/subject_search; __utmz=81379588.1722607121.66.51.utmcsr=search.douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/book/subject_search; __utma=30149280.413830873.1708960458.1722612328.1722618193.98; __utmt_douban=1; __utma=81379588.882311170.1709000614.1722612328.1722618193.68; __utmt=1; _pk_ref.100001.3ac3=%5B%22%22%2C%22%22%2C1722618195%2C%22https%3A%2F%2Fsearch.douban.com%2Fbook%2Fsubject_search%3Fsearch_text%3D9787505737631%26cat%3D1001%22%5D; _pk_ses.100001.3ac3=1; __utmb=30149280.4.10.1722618193; __utmb=81379588.4.10.1722618193");
                   // connection.header("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36");
                    doc = getDoc(url);
                }catch (Exception e){
                    log.error("请求豆瓣分页出错"+e.toString());
                    continue;
                }
                if(bookSum.get()==0){
                    log.info(doc.title());
                    log.info(url+listId);
                }
                //log.debug("处理到第"+bookSum+"本书");

                urls = dealPageData(doc);
                log.info("请求"+url+"返回"+urls.size());
                if(urls.size()==0){
                    log.info(Thread.currentThread().getName()+"最后一次请求"+url);
                }else{
                    log.info("第一本书"+urls.get(0).get("detailUrl"));
                }
                for(JSONObject ele:urls){
                    String detailUrl = (String)ele.get("detailUrl");
                    float rating = Float.parseFloat(ele.get("rating").toString());
                    String name =null;
                    int evaluateNum = 0;
                    DoubanBook resultBook = null;
                    int counterVal = counter.get();
                    counterVal++;
                    counter.set(counterVal);
                    log.info(Thread.currentThread().getName()+"处理第"+counterVal+"本书");
                    if(rating>ratingLine){
                        Document detail = null;
                        try{
                            int beginIndex = detailUrl.substring(0,detailUrl.length()-1).lastIndexOf("/");
                            String id  = detailUrl.substring(beginIndex+1,detailUrl.length()-1);
                            String tag = null;
                            if(url.contains("tag")){
                                int tagIndex = url.indexOf("tag");
                                int queIndex = url.indexOf("?");
                                tag = url.substring(tagIndex+4,queIndex-1).trim();
                            }

                            if(1==getDataType){
                                resultBook = doubanBookService.findOne(id);
                            }else if(0==getDataType) {
                                resultBook = getBookDetail(detailUrl,tag);
                            }else if(2==getDataType){
                                resultBook = doubanBookService.findOne(id);
                                /*if(!"企业史".equals(resultBook.getTag())){
                                    other++;
                                }*/
                                //log.info("other"+other);
                                log.info("exist"+exist);

                                if(null==resultBook){
                                    log.info("库里没有"+id+"---------------------------------------------------------------------------------------------------------------------");
                                    resultBook = getBookDetail(detailUrl,tag);
                                    //Toolkit.getDefaultToolkit().beep();
                                }else{
                                    exist++;
                                    //log.info("名称"+resultBook.getBookName());
                                }
                            }
                        }catch (DuplicateKeyException e){
                            log.error("书籍已经存在，跳过");
                            exist++;
                            continue;
                        }catch (Exception e2){
                            log.error("获取书籍详情出错",e2.getCause());
                            /*StackTraceElement[] eles =e2.getStackTrace();
                            if(null!=eles && eles.length>0){
                                log.error(eles[0].getLineNumber()+"行出错");
                            }*/

                            continue;
                        }

                        //System.out.println(name+"------"+url+"------"+isbn);
                        CapitalSearch capitalSearch = new CapitalSearch();
                        if(null==borrowBookService.findOne(resultBook.getIsbn().trim()) ){
                            //log.info("------"+detailUrl+"------"+resultBook.getIsbn());
                            //存库
                            int holding = capitalSearch.search(resultBook.getIsbn().trim());
                            BorrowBook book = new BorrowBook();
                            book.setBookName(resultBook.getBookName().trim());
                            book.setDetailUrl(detailUrl);
                            book.setIsbn(resultBook.getIsbn());
                            book.setRating(rating);
                            book.setListId(listId);
                            book.setClassify(classify);
                            book.setLibrary("capital");
                            book.setSource(source);
                            book.setListName(doc.title());
                            book.setInsertTime(new Date());
                            book.setIsCollect(0);
                            book.setEvaluateNum(resultBook.getEvaluateNum());
                            book.setHolding(holding);
                            try{
                                borrowBookService.saveNotNull(book);
                            }catch (DuplicateKeyException duplicateKeyException ){
                                borrowBookService.updateNotNullById(book);
                            }catch (Exception e){
                                log.error("borrowBook插入出错"+e.getMessage()+book.toString());
                            }

                        }

                    }

                }
            }catch(Exception e){
                log.error("出错了"+e.getMessage());
                log.error("StackTrace"+e.getStackTrace());
                log.error("local",e.getLocalizedMessage());
                log.error("cause",e.getCause());
                log.error("press"+e.getSuppressed());
                log.error("class"+e.getClass());
            }
            //翻页
            bookSum.set(bookSumIncrease(bookSum.get()));
            log.info("bookSum"+bookSum.get());
        }while (!isEmpty.get());
        log.info("\n\n\n\n\n\n");

        result.put("code",0);
        result.put("sum",bookSum.get());

        return result;
    }

}
